﻿// Necroz project team © <2015> <ArchLord2EMU>
// 
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
// 
// Author:Sagara
// Date:2015-09-13-22:46

using System;
using System.Collections.Concurrent;
using AL2Game.Network.Frames.Recv;
using AL2Game.Network.Frames.Send;
using ArchLord2Commons.Network;
using CM.Framework.Extensions;
using NLog;

namespace AL2Game.Network
{
    internal class GameFrameHandler : IAALFrameHandler
    {
        private static readonly Logger Log = LogManager.GetCurrentClassLogger();

        private static readonly ConcurrentDictionary<ushort, Type> ClientFrames = new ConcurrentDictionary<ushort, Type>();

        private static readonly ConcurrentDictionary<Type, ushort> ServerFrames = new ConcurrentDictionary<Type, ushort>();

        static GameFrameHandler()
        {
            InitilizeClientFrames();
            InitilizeServerFrames();

            Log.Info("Initilize frames done! Client frames:{0} server frames:{1}", ClientFrames.Count, ServerFrames.Count);
        }

        private static void InitilizeServerFrames()
        {
            ServerFrames.TryAdd(typeof (SfInitilizeConnection), 1001);
            ServerFrames.TryAdd(typeof (SfUnk1), 5221);
            ServerFrames.TryAdd(typeof (SfUnk2), 5222);
            ServerFrames.TryAdd(typeof (SfUnk3), 5051);
            ServerFrames.TryAdd(typeof (SfCharacterList), 5202);
            ServerFrames.TryAdd(typeof (SfSelectFraction), 5060);
            ServerFrames.TryAdd(typeof (SfCreateCharacter), 5062);
        }

        private static void InitilizeClientFrames()
        {
            ClientFrames.TryAdd(5050, typeof (RfGetClientAuthorizeData));
            ClientFrames.TryAdd(5201, typeof (RfGetCharacterList));
            ClientFrames.TryAdd(5059, typeof (RfSelectFraction));
            ClientFrames.TryAdd(5061, typeof (RfCreateCharacter));
        }

        public AALNetFrame GetFrameInstance(ushort opcode)
        {
            string opCodeLittleEndianHex = BitConverter.GetBytes(opcode).ToHex();

            bool contanis = ClientFrames.ContainsKey(opcode);

            if (!contanis)
            {
                return new RfUnk();
            }

            return (AALNetFrame)Activator.CreateInstance(ClientFrames[opcode]);
        }

        public ushort GetOpcode(Type t)
        {
            return ServerFrames[t];
        }
    }
}
